#기본세팅
import matplotlib as mpl
import pandas as pd
import numpy as np
%matplotlib inline
import networkx as nx
import matplotlib.pyplot as plt
#실제로 하기에는 너무 복잡해서 sample로 진행
file2 = pd.read_excel('network_sample_raw.xlsx', na_values = ['?', '??', 'N/A', 'NA', 'nan', 'NaN', '-nan', '-NaN', 'null', ' '])
file2
| 구분 | 대상조직 | 비교대상조직 | 유사도 | |
|---|---|---|---|---|
| 0 | 사업 | 사업1팀 | AI팀 | 0.50 |
| 1 | 사업 | 사업2팀 | 데이터팀 | 0.10 |
| 2 | 사업 | 사업2팀 | 인사팀 | 0.20 |
| 3 | 사업 | pc사업팀 | 인사팀 | 0.40 |
| 4 | 사업 | 콘솔사업팀 | AI팀 | 0.20 |
| 5 | 경영 | 재무실 | 인사팀 | 0.01 |
| 6 | 경영 | 재무실 | 개발2팀 | 1.00 |
| 7 | 경영 | 인사팀 | 사업1팀 | 0.67 |
| 8 | 경영 | 인사팀 | 개발1팀 | 0.45 |
| 9 | 경영 | 인사팀 | 디자인2팀 | 0.32 |
| 10 | 개발 | 개발1팀 | 사업1팀 | 0.03 |
| 11 | 개발 | 개발1팀 | 사업2팀 | 0.30 |
| 12 | 개발 | 개발1팀 | AI팀 | 1.00 |
| 13 | 개발 | 개발2팀 | 데이터팀 | 0.80 |
| 14 | 개발 | 개발2팀 | 인사팀 | 1.00 |
| 15 | 디자인 | 디자인1팀 | 인사팀 | 0.55 |
| 16 | 디자인 | 디자인1팀 | 사업1팀 | 1.00 |
| 17 | 디자인 | 디자인2팀 | 사업2팀 | 1.00 |
| 18 | 연구소 | AI팀 | 디자인1팀 | 1.00 |
| 19 | 연구소 | 데이터팀 | AI팀 | 0.42 |
import networkx as nx
import matplotlib.pyplot as plt
import pandas as pd
# 한글 폰트 사용을 위해서 세팅
from matplotlib import font_manager, rc
font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/malgun.ttf").get_name()
rc('font', family=font_name)
# 원시 데이터 정의
data_raw = [
('사업', '사업1팀', 'AI팀', 0.5),
('사업', '사업2팀', '데이터팀', 0.1),
('사업', '사업2팀', '인사팀', 0.2),
('사업', 'pc사업팀', '인사팀', 0.4),
('사업', '콘솔사업팀', 'AI팀', 0.2),
('경영', '재무실', '인사팀', 0.01),
('경영', '재무실', '개발2팀', 1.0),
('경영', '인사팀', '사업1팀', 0.67),
('경영', '인사팀', '개발1팀', 0.45),
('경영', '인사팀', '디자인2팀', 0.32),
('개발', '개발1팀', '사업1팀', 0.03),
('개발', '개발1팀', '사업2팀', 0.3),
('개발', '개발1팀', 'AI팀', 1.0),
('개발', '개발2팀', '데이터팀', 0.8),
('개발', '개발2팀', '인사팀', 1.0),
('디자인', '디자인1팀', '인사팀', 0.55),
('디자인', '디자인1팀', '사업1팀', 1.0),
('디자인', '디자인2팀', '사업2팀', 1.0),
('연구소', 'AI팀', '디자인1팀', 1.0),
('연구소', '데이터팀', 'AI팀', 0.42),
]
# 데이터 및 팀 그룹 매핑 딕셔너리 초기화
data = []
team_group_map = {}
# 원시 데이터 처리
for row in data_raw:
group, source, target, similarity = row
data.append({'group': group, 'source': source, 'target': target, 'similarity': similarity})
team_group_map[source] = group
# 방향성 그래프 생성
G = nx.DiGraph()
# 그래프에 엣지 및 노드 속성 추가
for item in data:
G.add_edge(item['source'], item['target'], weight=item['similarity'])
G.add_edge(item['target'], item['source'], weight=item['similarity']) # 양방향 edge 추가
G.nodes[item['source']]['group'] = item['group']
G.nodes[item['target']]['group'] = team_group_map.get(item['target'], None) # target 그룹이 team_group_map에 없는 경우 None으로 설정
# 노드 위치 계산
pos = nx.spring_layout(G)
# 노드 텍스트 위치를 위로 올리기 위한 새로운 위치 딕셔너리 생성
label_pos = {node: (x, y+0.1) for node, (x, y) in pos.items()}
# 그룹별 색상 매핑 정의
group_color_map = {
'경영': 'green',
'사업': 'blue',
'개발': 'red',
'디자인': 'yellow',
'사운드': 'purple',
'연구소': 'black'
}
# 노드 색상 계산
node_colors = [group_color_map[G.nodes[node]['group']] for node in G.nodes()]
# 그림 초기화 및 크기 설정
plt.figure(figsize=(12, 12))
# 노드 및 엣지 그리기
nx.draw_networkx_nodes(G, pos, node_color=node_colors, node_size=2000,)
nx.draw_networkx_edges(G, pos, edge_color='black', width=1)
# 엣지 가중치 레이블 추가
for e in G.edges():
x1, y1 = pos[e[0]]
x2, y2 = pos[e[1]]
x_mid = (x1 + x2) / 2
y_mid = (y1 + y2) / 2
weight_label = f"{G.edges[e]['weight']:.2f}"
plt.text(x_mid, y_mid, weight_label, fontsize=12)
# 노드 레이블 추가 (label_pos를 사용하여 텍스트를 위로 이동)
nx.draw_networkx_labels(G, label_pos, font_family=font_name, font_size=12, font_color='black')
# 축 및 격자 숨기기 및 표시
plt.axis('off')
plt.show()
import networkx as nx
import plotly.graph_objs as go
data_raw = [
('사업', '사업1팀', 'AI팀', 0.5),
('사업', '사업2팀', '데이터팀', 0.1),
('사업', '사업2팀', '인사팀', 0.2),
('사업', 'pc사업팀', '인사팀', 0.4),
('사업', '콘솔사업팀', 'AI팀', 0.2),
('경영', '재무실', '인사팀', 0.01),
('경영', '재무실', '개발2팀', 1.0),
('경영', '인사팀', '사업1팀', 0.67),
('경영', '인사팀', '개발1팀', 0.45),
('경영', '인사팀', '디자인2팀', 0.32),
('개발', '개발1팀', '사업1팀', 0.03),
('개발', '개발1팀', '사업2팀', 0.3),
('개발', '개발1팀', 'AI팀', 1.0),
('개발', '개발2팀', '데이터팀', 0.8),
('개발', '개발2팀', '인사팀', 1.0),
('디자인', '디자인1팀', '인사팀', 0.55),
('디자인', '디자인1팀', '사업1팀', 1.0),
('디자인', '디자인2팀', '사업2팀', 1.0),
('연구소', 'AI팀', '디자인1팀', 1.0),
('연구소', '데이터팀', 'AI팀', 0.42),
]
# read data
data = file2
# create nodes and links list
nodes = list(set(data.iloc[:,1:-1].values.flatten()))
# 데이터 목록 및 team_group_map 딕셔너리 초기화
data = []
team_group_map = {}
# data_raw의 정보로부터 데이터 목록과 team_group_map 딕셔너리 생성
for row in data_raw:
group, source, target, similarity = row
data.append({'group': group, 'source': source, 'target': target, 'similarity': similarity})
team_group_map[source] = group
# 빈 그래프 생성
G = nx.Graph()
# 데이터 목록 및 team_group_map을 사용하여 엣지 추가 및 노드 속성 설정
for item in data:
G.add_edge(item['source'], item['target'], weight=item['similarity'])
G.nodes[item['source']]['group'] = team_group_map[item['source']]
G.nodes[item['target']]['group'] = team_group_map.get(item['target'], None) # target 그룹이 team_group_map에 없는 경우 None으로 설정
# 스프링 레이아웃 알고리즘을 사용하여 노드의 레이아웃 위치 계산
pos = nx.spring_layout(G, dim=3)
# 노드의 X, Y, Z 좌표 가져오기
Xn = [pos[k][0] for k in G.nodes()]
Yn = [pos[k][1] for k in G.nodes()]
Zn = [pos[k][2] for k in G.nodes()]
# 엣지의 끝점 좌표에 대한 X, Y, Z 좌표의 빈 목록 초기화
Xe = []
Ye = []
Ze = []
# 엣지의 끝점 좌표로 Xe, Ye, Ze 목록을 채움
for e in G.edges():
Xe += [pos[e[0]][0], pos[e[1]][0], None]
Ye += [pos[e[0]][1], pos[e[1]][1], None]
Ze += [pos[e[0]][2], pos[e[1]][2], None]
# 가중치 레이블을 위한 X, Y, Z 좌표의 빈 목록 초기화
Xe_mid = []
Ye_mid = []
Ze_mid = []
# 엣지의 중간 지점 좌표로 Xe_mid, Ye_mid, Ze_mid 목록을 채움
for e in G.edges():
Xe_mid.append((pos[e[0]][0] + pos[e[1]][0]) / 2)
Ye_mid.append((pos[e[0]][1] + pos[e[1]][1]) / 2)
Ze_mid.append((pos[e[0]][2] + pos[e[1]][2]) / 2)
# 그룹에 대한 컬러 맵 정의
group_color_map = {
'경영': 'green',
'사업': 'blue',
'개발': 'red',
'디자인': 'yellow',
'사운드': 'purple',
'연구소': 'black'
}
# 그룹에 따라 노드 색상 가져오기
node_colors = [group_color_map[G.nodes[node]['group']] for node in G.nodes()]
# 엣지 가중치에 기반한 엣지 레이블 가져오기
edge_labels = [f"{G.edges[e]['weight']:.2f}" for e in G.edges()]
# 엣지에 대한 트레이스 정의
trace_edges = go.Scatter3d(x=Xe, y=Ye, z=Ze, mode='lines', line=dict(color='black', width=2),
text=list(G.edges()), hoverinfo='text', textposition="top center")
# 노드에 대한 트레이스 정의
trace_nodes = go.Scatter3d(x=Xn, y=Yn, z=Zn, mode='markers+text', marker=dict(symbol='circle', size=5,color=node_colors),
text=list(G.nodes()), hoverinfo='text', textposition="top center")
# 엣지 가중치 레이블 트레이스 생성
trace_edge_labels = go.Scatter3d(x=Xe_mid, y=Ye_mid, z=Ze_mid, mode='text', text=edge_labels, textfont=dict(color='black', size=10),
hoverinfo='none', textposition="bottom center")
# 축 속성 설정
axis = dict(showbackground=False, showline=True, zeroline=True, showgrid=True, showticklabels=False, title='')
# 3D 네트워크 그래프에 대한 레이아웃 정의
layout = go.Layout(title="3D Network Graph using Plotly", width=800, height=800, showlegend=False,
scene=dict(xaxis=dict(axis), yaxis=dict(axis), zaxis=dict(axis)))
# 엣지, 노드 및 엣지 레이블을 포함하는 그림을 정의하고 표시
fig = go.Figure(data=[trace_edges, trace_nodes,trace_edge_labels], layout=layout)
fig.show()